<template>
  <div class="simple-menu-container" :class="{ 'collapsed': getCollapsed }">
    <div class="simple-menu-logo" v-if="!getCollapsed" @click="goHome">
      <img src="/@/assets/images/header_logo.png" alt="logo" />
    </div>
    <Menu
      :class="prefixCls"
      v-bind="getBindValues"
      :openKeys="getOpenKeys"
      :selectedKeys="[activeName]"
      :mode="mode"
      @select="handleSelect"
      :theme="theme"
      :inline-collapsed="getCollapsed"
    >
      <template v-for="item in items" :key="item.path">
        <SimpleSubMenu :item="item" :theme="theme" :isThemeBright="isThemeBright" />
      </template>
    </Menu>
    <div class="menu-bottom-buttons">
      <div class="bottom-button frame-icon" @click="handleToggleCollapsed">
        <img src="/@/assets/images/icon-frame.png" alt="system" />
      </div>
      <div class="bottom-button search-icon" @click="handleSearchClick">
        <img src="/@/assets/images/icon-search.png" alt="search" />
      </div>
    </div>
  </div>
</template>
<script lang="ts">
  import type { MenuState } from './types';
  import type { Menu as MenuType } from '/@/router/types';
  import type { RouteLocationNormalizedLoaded } from 'vue-router';
  import { defineComponent, computed, ref, unref, reactive, toRefs, watch } from 'vue';
  import { useDesign } from '/@/hooks/web/useDesign';
  import Menu from './components/Menu.vue';
  import SimpleSubMenu from './SimpleSubMenu.vue';
  import { listenerRouteChange } from '/@/logics/mitt/routeChange';
  import { propTypes } from '/@/utils/propTypes';
  import { REDIRECT_NAME } from '/@/router/constant';
  import { useRouter } from 'vue-router';
  import { isFunction, isUrl } from '/@/utils/is';
  import { URL_HASH_TAB } from '/@/utils';
  import { useAppStore } from '/@/store/modules/app';
  import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
  import { useUserStore } from '/@/store/modules/user';
  import { PageEnum } from '/@/enums/pageEnum';

  import { useOpenKeys } from './useOpenKeys';

  export default defineComponent({
    name: 'SimpleMenu',
    components: {
      Menu,
      SimpleSubMenu,
    },
    inheritAttrs: false,
    props: {
      items: {
        type: Array as PropType<MenuType[]>,
        default: () => [],
      },
      collapse: propTypes.bool,
      mixSider: propTypes.bool,
      theme: propTypes.string,
      accordion: propTypes.bool.def(true),
      collapsedShowTitle: propTypes.bool,
      beforeClickFn: {
        type: Function as PropType<(key: string) => Promise<boolean>>,
      },
      isSplitMenu: propTypes.bool,
      mode: {
        type: String,
        default: 'inline',
      },
    },
    emits: ['menuClick'],
    setup(props, { attrs, emit }) {
      const currentActiveMenu = ref('');
      const isClickGo = ref(false);
      const appStore = useAppStore();
      const isThemeBright = ref(false);
      const { getCollapsed, toggleCollapsed } = useMenuSetting();
      const router = useRouter();

      const menuState = reactive<MenuState>({
        activeName: '',
        openNames: [],
        activeSubMenuNames: [],
      });

      const { currentRoute } = useRouter();
      const { prefixCls } = useDesign('simple-menu');
      const { items, accordion, mixSider, collapse } = toRefs(props);

      const { setOpenKeys, getOpenKeys } = useOpenKeys(
        menuState,
        items,
        computed(() => accordion.value ?? true),
        computed(() => mixSider.value ?? false),
        computed(() => collapse.value ?? false)
      );

      const getBindValues = computed(() => ({ ...attrs, ...props }));
      const userStore = useUserStore();
      const goHome = () => {
        router.push(userStore.getUserInfo.homePath || PageEnum.BASE_HOME);
      }

      watch(
        () => props.collapse,
        (collapse) => {
          if (collapse) {
            menuState.openNames = [];
          } else {
            setOpenKeys(currentRoute.value.path);
          }
        },
        { immediate: true }
      );

      watch(
        () => props.items,
        () => {
          if (!props.isSplitMenu) {
            return;
          }
          setOpenKeys(currentRoute.value.path);
        },
        { flush: 'post' }
      );
      // update-begin--author:liaozhiyang---date:20240408---for：【QQYUN-8922】左侧导航栏文字颜色调整区分彩色和暗黑
      watch(
        () => appStore.getProjectConfig.menuSetting,
        (menuSetting) => {
          isThemeBright.value = !!menuSetting?.isThemeBright;
        },
        { immediate: true, deep: true }
      );
      // update-end--author:liaozhiyang---date:20240408---for：【QQYUN-8922】左侧导航栏文字颜色调整区分彩色和暗黑
      listenerRouteChange((route) => {
        if (route.name === REDIRECT_NAME) return;

        currentActiveMenu.value = route.meta?.currentActiveMenu as string;
        handleMenuChange(route);

        if (unref(currentActiveMenu)) {
          menuState.activeName = unref(currentActiveMenu);
          setOpenKeys(unref(currentActiveMenu));
        }
      });

      async function handleMenuChange(route?: RouteLocationNormalizedLoaded) {
        if (unref(isClickGo)) {
          isClickGo.value = false;
          return;
        }
        const path = (route || unref(currentRoute)).path;

        menuState.activeName = path;

        setOpenKeys(path);
      }

      async function handleSelect(key: string) {
        if (isUrl(key)) {
          // update-begin--author:sunjianlei---date:20220408---for: 【VUEN-656】配置外部网址打不开，原因是带了#号，需要替换一下
          let url = key.replace(URL_HASH_TAB, '#');
          window.open(url)
          //openWindow(url);
          // update-begin--author:sunjianlei---date:20220408---for: 【VUEN-656】配置外部网址打不开，原因是带了#号，需要替换一下
          return;
        }
        // update-begin--author:liaozhiyang---date:20240227---for：【QQYUN-6366】内部路由也可以支持采用新浏览器tab打开
        const findItem = getMatchingMenu(props.items, key);
        if (findItem?.internalOrExternal == true) {
          window.open(location.origin + key);
          return;
        }
        // update-end--author:liaozhiyang---date:20240227---for：【QQYUN-6366】内部路由也可以支持采用新浏览器tab打开

        const { beforeClickFn } = props;
        if (beforeClickFn && isFunction(beforeClickFn)) {
          const flag = await beforeClickFn(key);
          if (!flag) return;
        }

        emit('menuClick', key);

        isClickGo.value = true;
        setOpenKeys(key);
        menuState.activeName = key;
      }

      /**
       * 2024-02-27
       * liaozhiyang
       * 获取菜单中匹配的path所在的项
       */
      const getMatchingMenu = (menus, path) => {
        for (let i = 0, len = menus.length; i < len; i++) {
          const item = menus[i];
          if (item.path === path && !item.redirect && !item.paramPath) {
            return item;
          } else if (item.children?.length) {
            const result = getMatchingMenu(item.children, path);
            if (result) {
              return result;
            }
          }
        }
        return '';
      }

      function handleToggleCollapsed() {
        toggleCollapsed();
      }

      function handleSearchClick() {
        router.push('/search');
      }

      return {
        prefixCls,
        getBindValues,
        handleSelect,
        getOpenKeys,
        ...toRefs(menuState),
        isThemeBright,
        handleToggleCollapsed,
        handleSearchClick,
        getCollapsed,
        goHome
      };
    },
  });
</script>
<style lang="less">
  @import './index.less';

  .simple-menu-container {
    .simple-menu-logo {
      // height: @header-height;
      padding: 10px 16px 0 5px;
      display: flex;
      align-items: center;
      background-color: @theme-bg-color;

      img {
        height: 60px;
        width: auto;
      }
    }

    transition: all 0.2s;

    &.collapsed {
      .simple-menu-logo {
        padding: 10px 16px;
        justify-content: center;

        img {
          width: 32px;
          height: 32px;
        }
      }

      .menu-bottom-buttons {
        width: 64px;
        padding: 0 8px 10px 8px;
      }
    }
  }

  @simple-prefix-cls: ~'@{namespace}-simple-menu';
  @prefix-cls: ~'@{namespace}-menu';

  .@{prefix-cls} {
    background-color: @theme-bg-color !important;

    .anticon {
      color: #fff !important;
    }

    .ant-menu-submenu-arrow {
      color: #fff !important;
    }

    &-item {
      color: #fff !important;

      .anticon {
        color: #fff !important;
      }

      &:hover {
        background-color: darken(@theme-bg-color, 5%) !important;
      }

      &-selected {
        background-color: darken(@theme-bg-color, 10%) !important;
        color: #fff !important;
      }
    }

    &-submenu {
      color: #fff !important;
      background-color: @theme-bg-color !important;

      &-arrow {
        color: #fff !important;
      }

      &-title {
        color: #fff !important;

        .anticon {
          color: #fff !important;
        }

        &:hover {
          background-color: darken(@theme-bg-color, 5%) !important;
        }
      }

      &-selected {
        > .@{prefix-cls}-submenu-title {
          background-color: darken(@theme-bg-color, 10%) !important;
          color: #fff !important;
        }
      }
    }

    &-dark {
      background-color: @theme-bg-color !important;

      .@{prefix-cls}-item {
        color: #fff !important;

        .anticon {
          color: #fff !important;
        }

        &:hover {
          background-color: darken(@theme-bg-color, 5%) !important;
        }

        &-selected {
          background-color: darken(@theme-bg-color, 10%) !important;
        }
      }

      .@{prefix-cls}-submenu {
        color: #fff !important;

        &-arrow {
          color: #fff !important;
        }

        &-title {
          color: #fff !important;

          .anticon {
            color: #fff !important;
          }
        }
      }
    }

    .@{simple-prefix-cls} {
      &-sub-title {
        color: #fff !important;
      }
    }
  }

  .menu-bottom-buttons {
    position: fixed;
    bottom: 0;
    left: 0;
    width: 200px;
    height: 48px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    background-color: @theme-bg-color;
    padding: 0 16px 10px 16px;
    // border-top: 1px solid rgba(255, 255, 255, 0.1);

    .bottom-button {
      cursor: pointer;
      width: 22px;
      // height: 32px;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 4px;
      transition: all 0.3s;

      &:hover {
        background-color: darken(@theme-bg-color, 5%);
      }
    }
    .search-icon{
      img {
        width: 25px;
        height: auto;
      }
    }
    .frame-icon{
      img {
        width: 16px;
        height: auto;
      }
    }
  }
</style>
